/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package javaapplication1;


import java.io.File;


import java.util.Timer;
import java.util.TimerTask;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.List;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.swt.widgets.MessageBox;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;


/**
 *
 * @author Oren
 */
public class GUI {
    //
    private static Shell shell;
    // The List for Group 2 : robot for the robot list , files for program list
    private static List robots,files;
    // The User Interface Text options
    private static Text textName, textBoxName , textBoxPosx,textBoxPosy,
            textRobotPosx,textRobotPosy;
    // The User comobo Boxes
    private static Combo comboType;
    // The User Interface Buttons
    private static Button buttonArm,buttonSmart, buttonAdd;
    // TODO - MOVE from here to local
    private static Label labelName, labelType;
    // The Canvas where all the robots and boxes are displayed
    private static Canvas canvas;
    // The robot evnironement
    private static Simulation sim;
    // The boxes evnironement
    private static Boxes boxes;
    // The command interface
    private static Commands com;
    // the strings for the robot and file lists
    private static String rname, pname;
    // the error messageBox
    private static MessageBox messageBox ;
    // the Simulation Timer
    private static Timer simti;
    // the Simulation flag
    private static boolean simison;




// The RedrawTask is a TimerTask which refresh the canvas.
    private static class RedrawTask extends TimerTask{
        Canvas c;
        Display d;
        public void setCanvas(Canvas c){
            this.c=c;
            d=c.getDisplay();
        }
        @Override
        public synchronized void run() {
           d.asyncExec(new Runnable(){
           public void run() {
                if(!c.isDisposed()){
                c.redraw();
                c.update();
            }
           }
          });
         }
    }

// The  is a TimerTask which refresh the simulation(and let other threads to run).
    private static class SimTask extends TimerTask{

        @Override
        public synchronized void run() {
            try {
                com.runCommand("Simulate 1 seconds");
            } catch (Exception ex) {
                Logger.getLogger(GUI.class.getName()).log(Level.SEVERE, null, ex);
            }

        }

    }



    // the error message box interface
    private static void showMessage(String message)
    {
        messageBox.setMessage(message);
        messageBox.open();                
    }
    private static void InitAddRobot(final Shell dialog) throws Exception
    {
        // Initialize the Dialog Box

        final Label label = new Label(dialog, SWT.NONE);
        label.setText("Pos.X:");
     

        GridData gridData1 = new GridData(GridData.FILL_HORIZONTAL);
        gridData1.grabExcessHorizontalSpace = true;
        textRobotPosx = new Text(dialog, SWT.SINGLE | SWT.BORDER );
        textRobotPosx.setLayoutData(gridData1);

        final Label labely = new Label(dialog, SWT.NONE);
        labely.setText("Pos.Y:");
        textRobotPosy = new Text(dialog, SWT.SINGLE | SWT.BORDER );
        textRobotPosy.setLayoutData(gridData1);


        // the dialog buttons ; OK
        GridData gridDataOK = new GridData(GridData.FILL_HORIZONTAL);
        gridDataOK.grabExcessHorizontalSpace = true;
        gridDataOK.horizontalSpan = 2;
        final Button buttonOK = new Button(dialog, SWT.PUSH);
        buttonOK.setText("OK");
        buttonOK.setLayoutData(gridDataOK);


        // the dialog buttons ; Cancel
        Button buttonCancel = new Button(dialog, SWT.PUSH);
        buttonCancel.setText("Cancel");
        buttonCancel.setLayoutData(gridDataOK);

// **********************************************************************//
        // What to do when OK is pressed (Add Box DialogBox)
// **********************************************************************//
        buttonOK.addListener(SWT.Selection, new Listener() {
            public void handleEvent(Event e) {
                switch (e.type) {
                    case SWT.Selection:
                    {
                        try{
                            String type1;
                            String type2;
                            String robotname;
                            String position;

                            // get the first type (Aibo,Rv1,RV2)
                            type1 = comboType.getText();
                            // get the second type
                            if (buttonArm.getSelection()) {
                                if (buttonSmart.getSelection()) {
                                    type2 = "all";
                                } else {
                                    type2 = "arm";
                                }
                            } else if (buttonSmart.getSelection()) {
                                type2 = "smartKit";
                            } else {
                                type2 = "none";
                            }
                            // get the robot starting position
                            position = textRobotPosx.getText();
                            position = position.concat(" "+textRobotPosy.getText());
                            // create the string for the run command
                            String cmd = "Init type ";
                            // add the type part
                            cmd = cmd.concat(type1);
                            // add the position and name part
                            robotname = textName.getText();
                            cmd = cmd.concat(" at " + position + " named " + robotname);
                            if (!type2.equalsIgnoreCase("none"))
                                cmd = cmd.concat(" with " + type2);
                            com.runCommand(cmd);
                            // add the robot to the robot list on group 2
                            robots.add(robotname);
                            dialog.close();
                      
                        break;
                    }catch (Exception f){showMessage(f.getMessage());}
                    }
                }

            }
        });
// **********************************************************************//
        // What to do when Cancel is pressed (Add Box DialogBox)
// **********************************************************************//
         buttonCancel.addListener(SWT.Selection, new Listener() {
            public void handleEvent(Event e) {
                switch (e.type) {
                    case SWT.Selection:
                    {
                        dialog.close();
                        break;
                    }
                }

            }
        });
    }




    private static void initCreationList(Group group1) {
        labelName = new Label(group1,SWT.NULL);
        GridData gridData = new GridData(GridData.FILL_HORIZONTAL);
        gridData.grabExcessHorizontalSpace = true;
        textName = new Text(group1, SWT.SINGLE | SWT.BORDER);
        textName.setLayoutData(gridData);
        labelName.setText("Name ");

        buttonArm = new Button(group1,SWT.CHECK);
        new Label(group1,SWT.NONE).setText("add Arm");

        // the "Add" button
        buttonAdd = new Button(group1, SWT.PUSH);
        buttonAdd.setText("Add");
        GridData gridData2 = new GridData(GridData.FILL_BOTH);
        gridData2.grabExcessVerticalSpace = true;
        gridData2.verticalSpan=2;
        buttonAdd.setLayoutData(gridData2);

        // 2nd Row
        // the type label
        labelType = new Label(group1,SWT.NULL);
        GridData gridData1 = new GridData(GridData.FILL_HORIZONTAL);
        gridData1.grabExcessHorizontalSpace = true;
        // the type combo drop_down box
        comboType = new Combo(group1, SWT.DROP_DOWN | SWT.BORDER);
        // the posiable values:
        comboType.add("RV1");
        comboType.add("RV2");
        comboType.add("Aibo");

        labelType.setText("Type ");

        // do you want a smart robot ?
        buttonSmart = new Button(group1,SWT.CHECK);
        new Label(group1,SWT.NONE).setText("Smart Robot");

// **********************************************************************//
        // What to do when ADD is pressed (Main Window)
// **********************************************************************//
        buttonAdd.addListener(SWT.Selection, new Listener() {
            public void handleEvent(Event e) {

                    switch (e.type) {
                    case SWT.Selection:
                    {
                    try {

                        // the dialog box is a new shell named dialog
                        Shell dialog = new Shell(shell, SWT.APPLICATION_MODAL
                        | SWT.DIALOG_TRIM);
                        dialog.setText("Initilaize Position");
                        dialog.setSize(170, 90);
                        dialog.setLayoutData(new GridData(SWT.FILL,SWT.CENTER,true,false));
                        dialog.setLayout(new GridLayout(4,false));
                        InitAddRobot(dialog);
                        dialog.open();
                       
                        
                    } catch (Exception ex) {showMessage(ex.getMessage());}
                        break;
                }

            }
        }
        });

}

    private static void initLists(Group g){
            // headlines:
            new Label(g,SWT.NONE).setText("Robots List");
            new Label(g,SWT.NONE);	// blank
            new Label(g,SWT.NONE).setText("Files List");

            robots=new List(g,SWT.BORDER | SWT.V_SCROLL);
            robots.setLayoutData(new GridData(150,80));
            Button b=new Button(g,SWT.PUSH);
            b.setText("<-");
            files=new List(g,SWT.BORDER | SWT.V_SCROLL);
            files.setLayoutData(new GridData(150,80));
            File f=new File(".");
            files.setItems(f.list());

// **********************************************************************//
        // What to do when "<-" is pressed (Main Window)
// **********************************************************************//
            b.addListener(SWT.Selection, new Listener() {
                public void handleEvent(Event e) {

                    switch (e.type) {
                    case SWT.Selection:
                    try{
                    {
                        int temp = robots.getSelectionIndex();
                        // get the first word (the robot name)
                        rname = robots.getItem(temp).split(" ")[0];

                        int temp2 = files.getSelectionIndex();
                        // get the program name
                        pname = files.getItem(temp2);

                        // the command format:
                        //"Assign (\\w+) with (.+)"
                        String cmd = "Assign ";
                        // Add the robot name from robots list
                        // the selected element is added
                        cmd = cmd.concat(rname);
                        cmd = cmd.concat(" with ");
                        // Add the program name from files list
                        // the selected element is added
                        cmd = cmd.concat(pname);
                        com.runCommand(cmd);
                        // change the robot name to include the program name

                        int i = robots.getSelectionIndex();

                            robots.setItem(i, rname+" "+pname);
                        break;
                    }
                    }catch (Exception f){

                      showMessage(f.getMessage());
                    }
                }
            }
        });

    }
    private static void initDialog(final Shell dialog)
    {
        final Label blabel = new Label(dialog, SWT.NONE);
        blabel.setText("Box Name:");
        

        GridData gridData = new GridData(GridData.FILL_HORIZONTAL);
        gridData.grabExcessHorizontalSpace = true;
        gridData.horizontalSpan = 3;
        textBoxName = new Text(dialog, SWT.SINGLE | SWT.BORDER);
        textBoxName.setLayoutData(gridData);

        final Label label = new Label(dialog, SWT.NONE);
        label.setText("Pos.X:");
     

        GridData gridData1 = new GridData(GridData.FILL_HORIZONTAL);
        gridData1.grabExcessHorizontalSpace = true;
        textBoxPosx = new Text(dialog, SWT.SINGLE | SWT.BORDER );
        textBoxPosx.setLayoutData(gridData1);

        final Label labely = new Label(dialog, SWT.NONE);
        labely.setText("Pos.Y:");
        textBoxPosy = new Text(dialog, SWT.SINGLE | SWT.BORDER );
        textBoxPosy.setLayoutData(gridData1);


        // the dialog buttons ; OK
        GridData gridDataOK = new GridData(GridData.FILL_HORIZONTAL);
        gridDataOK.grabExcessHorizontalSpace = true;
        gridDataOK.horizontalSpan = 2;
        final Button buttonOK = new Button(dialog, SWT.PUSH);
        buttonOK.setText("OK");
        buttonOK.setLayoutData(gridDataOK);


        // the dialog buttons ; Cancel
        Button buttonCancel = new Button(dialog, SWT.PUSH);
        buttonCancel.setText("Cancel");
        buttonCancel.setLayoutData(gridDataOK);

// **********************************************************************//
        // What to do when OK is pressed (Add Box DialogBox)
// **********************************************************************//
        buttonOK.addListener(SWT.Selection, new Listener() {
            public void handleEvent(Event e) {
                switch (e.type) {
                    case SWT.Selection:
                    {
                        try{
                        String boxname , boxposx, boxposy;
                        // the format :
                        // "PutBox at ([-]*\\d+) ([-]*\\d+) named (\\w+)"
                        // get the box name
                        boxname = textBoxName.getText();
                        boxposx = textBoxPosx.getText();
                        boxposy = textBoxPosy.getText();

                    

                        // create the string for the run command
                        String cmd = "PutBox at ";
                        cmd = cmd.concat(boxposx);
                        cmd = cmd.concat(" ");
                        cmd = cmd.concat(boxposy);
                        // add the position and name part
                        cmd = cmd.concat(" named " + boxname);
                        com.runCommand(cmd);
                        dialog.close();
                        break;
                    }catch (Exception f){showMessage(f.getMessage());}
                    }
                }

            }
        });
// **********************************************************************//
        // What to do when Cancel is pressed (Add Box DialogBox)
// **********************************************************************//
         buttonCancel.addListener(SWT.Selection, new Listener() {
            public void handleEvent(Event e) {
                switch (e.type) {
                    case SWT.Selection:
                    {
                        dialog.close();
                        break;
                    }
                }

            }
        });



    }


    public static void main(String[] args) {
        sim = new Simulation();
        boxes = new Boxes();
        com = new Commands(sim,boxes);
        simison = false;
        

        Display display = new Display();
        shell = new Shell(display);
        shell.setLayout(new GridLayout(2,false));
        shell.setText("Advanced Programming exercise 1");
        shell.setSize(700, 600);

        // -------- Main window parts------------

        // The menu objects:
        // manuBar is responsable for the lication of file and box sub menu
        Menu    fileMenu , boxMenu;

        // these are the GUI items
        MenuItem fileMenuHeader, boxMenuHeader;

        // the Error Message Box
        messageBox = new MessageBox(shell, SWT.ICON_ERROR);
     


        // these are the items sub options
        MenuItem startSimItem , stopSimItem , exitItem , addBoxItem;
        Menu menuBar = new Menu (shell,SWT.BAR);

        // add the file button location and name.
        fileMenuHeader = new MenuItem(menuBar, SWT.CASCADE);
        fileMenuHeader.setText("&File");
        fileMenu = new Menu(shell, SWT.DROP_DOWN);
        fileMenuHeader.setMenu(fileMenu);

        // add the file sub options :
        startSimItem = new MenuItem(fileMenu, SWT.PUSH);
        startSimItem.setText("&Start Simulation");
// **********************************************************************//
        // What to do when Start Simulation sub menu is pressed (Main Window)
// **********************************************************************//
        startSimItem.addListener(SWT.Selection, new Listener() {
            public void handleEvent(Event e) {
                try {
                    
                    // The simison flag make sure that the user won't press
                    // the start button more then once
                    if (simison == false)
                    {
                        SimTask simtask = new SimTask();
                        simison = true;
                        simti =new Timer();
                        simti.scheduleAtFixedRate(simtask , 0, 1000);
                    }
                    
                }  catch (Exception f){ showMessage(f.getMessage());}

            }
        });
        stopSimItem = new MenuItem(fileMenu, SWT.PUSH);
        stopSimItem.setText("&Stop Simulation");
// **********************************************************************//
        // What to do when Stop Simulation sub menu is pressed (Main Window)
// **********************************************************************//
       stopSimItem.addListener(SWT.Selection, new Listener() {
            public void handleEvent(Event e) {
                // The simison flag make sure that the user won't press
                // the stop button before he pressed the start button
                if (simison = true)
                        simti.cancel();
            }
        });
        exitItem = new MenuItem(fileMenu, SWT.PUSH);
        exitItem.setText("&Exit");
// **********************************************************************//        
        // What to do when Exit Sub Menu is pressed (Main Window)
// **********************************************************************//
        exitItem.addListener(SWT.Selection, new Listener() {
            public void handleEvent(Event e) {
                try {
                    com.runCommand("Exit");
                }  catch (Exception f){ showMessage(f.getMessage());}

            }
        });

         // add the box button location and name.
        boxMenuHeader = new MenuItem(menuBar, SWT.CASCADE);
        boxMenuHeader.setText("&Box");
        boxMenu = new Menu(shell, SWT.DROP_DOWN);
        boxMenuHeader.setMenu(boxMenu);

        // add the box sub options :
        addBoxItem = new MenuItem(boxMenu, SWT.PUSH);
        addBoxItem.setText("&Add Box");
// **********************************************************************//
        // What to do when ADD BOX sub menu is pressed (Main Window)
// **********************************************************************//
        addBoxItem.addListener(SWT.Selection, new Listener() {
            public void handleEvent(Event e) {
                // the dialog box is a new shell named dialog
                Shell dialog = new Shell(shell, SWT.APPLICATION_MODAL
                | SWT.DIALOG_TRIM);
                dialog.setText("Add Box");
                dialog.setSize(200, 120);
                dialog.setLayoutData(new GridData(SWT.FILL,SWT.CENTER,true,false));
                dialog.setLayout(new GridLayout(4,false));
                initDialog(dialog);
                dialog.open();
            }
        });


        // ==== Group 1
        //set the group of create robot
        Group group1=new Group(shell,SWT.SHADOW_IN);
        group1.setText("Create Robot");
        // makes it to take as much space it can:
        group1.setLayoutData(new GridData(SWT.FILL,SWT.CENTER,true,false));
        // set the group layout to be ???
        group1.setLayout(new GridLayout(5,false));
        /* call an "init" method to insert components into group1,
         * see what happens in group2, to get a hint on how to do it.
         */
        initCreationList(group1);

        // ==== Group 2
        //set the group of the lists
        Group group2=new Group(shell,SWT.SHADOW_IN);
        // set the group layout to be 3 cols
        group2.setLayout(new GridLayout(3,false));
        // init the group components
        initLists(group2);	// init the lists into group2

        // ==== the big drawing Canvas
        canvas=new Canvas(shell,SWT.BORDER);
        // set the canvas to take 2 cells
        canvas.setLayoutData(new GridData(SWT.FILL,SWT.FILL,false,true,2,1));
        canvas.setBackground(display.getSystemColor(1));
        canvas.addPaintListener(new DrawEnvironment(sim,boxes));


        // Multi Thread Canvas update
        RedrawTask rt=new RedrawTask();
        rt.setCanvas(canvas);
        Timer ti=new Timer();
        ti.scheduleAtFixedRate(rt, 0, 100);

        // --------- end of main window part --------
        shell.setMenuBar(menuBar);
        shell.open();
        // Set up the event loop.
        while (!shell.isDisposed()) {
          if (!display.readAndDispatch()) {
            // If no more entries in the event queue
            display.sleep();
          }
        }
        ti.cancel();
        display.dispose();
    }


}

